
#include "key_word_tree.h"
#include <iostream>

std::vector<std::string> SplitWord(std::string words)
{
    std::vector<std::string> result;
    for (size_t i = 0; i < words.size(); i++)
    {
        int size = 0;
        if (words[i] & 0x80)
        {
            char temp = words[i];
            temp <<= 1;
            do
            {
                temp <<= 1;
                ++size;
            } while (temp & 0x80);
        }
        std::string subWord = words.substr(i, size + 1);
        result.push_back(subWord);
        i += size;
    }
    return result;
}

std::string ComposeStringVector(std::vector<std::string> vec)
{
    std::string res;
    for(auto it : vec)
    {
        res += it;
    }
    return res;
}

void ReplaceFilterWord(std::vector<std::string> &source,std::vector<KeyWordArea> areas)
{
    
    for(KeyWordArea area : areas)
    {
        for(size_t index = area.start;index < area.start + area.length ;index ++)
        {
            std::cout << "replace : " << source[index] << std::endl;
            source[index] = "*";
        }
    }
}


const std::string KeyWordTree::rootKey = "root";
KeyWordTree::KeyWordTree() : root_(nullptr)
{
    root_ = new KeyWordTreeNode(KeyWordTree::rootKey,nullptr);
}

KeyWordTree::~KeyWordTree()
{
    delete root_;
}

KeyWordArea KeyWordTree::GetKeyWordArea(const std::vector<std::string> strVec,size_t start)
{
    KeyWordArea area((int)start,0);
    if(strVec.size()<=0) return area;
    
    KeyWordTreeNode *treeNode = NULL;
    KeyWordTreeNode *tempNode = root_;
    do{
        int curIndex = area.start + area.length;
        treeNode = NULL;
        while(strVec.size() > curIndex)
        {
            const std::string curKey = strVec.at(curIndex);
            if(curKey == " ")
            {
                curIndex++;
                area.length++;
            }
            else
            {
                treeNode = tempNode->GetChildWithKey(curKey);
                break;
            }
        }
        
        
        if(NULL == treeNode)
        {
            KeyWordTreeNode *endNode = tempNode->GetChildWithKey(KeyWordTreeNode::endKey);
            if(NULL == endNode)
            {
                area.length = 0;
            }
        }
        else
        {
            tempNode = treeNode;
            area.length++;
        }
    }while(treeNode != NULL);
    return area;
}


std::vector<KeyWordArea> KeyWordTree::GetKeyWordAreas(const std::vector<std::string> strVec)
{
    std::vector<KeyWordArea> result;
    for(size_t index = 0;index < strVec.size();index++)
    {
        KeyWordArea area = GetKeyWordArea(strVec,index);
        if(area.length>0)
        {
            result.push_back(area);
            index -= 1;
        }
        index += area.length;
    }
    return result;
}

KeyWordTreeNode *KeyWordTree::GetRootNode()
{
    return root_;
}


KeyWordTreeNode::KeyWordTreeNode(const std::string &key,KeyWordTreeNode *parent) : key_(key),parent_(parent)
{
}

const std::string KeyWordTreeNode::endKey = "";

KeyWordTreeNode::~KeyWordTreeNode()
{
    for (auto it : children_)
    {
        delete it;
    }
    children_.clear();
}

const std::string KeyWordTreeNode::GetKey()
{
    return key_;
}

int KeyWordTreeNode::CompareKey(const std::string &key)
{
    if (key == key_)
        return 0;
    return key > key_ ? 1 : -1;
}

KeyWordTreeNode* KeyWordTreeNode::AddChild(const std::string &key)
{
    std::cout << "添加关键字 : " << key << std::endl;
    KeyWordTreeNode *node = GetChildWithKey(key);
    if (node == nullptr)
    {
        node = new KeyWordTreeNode(key,this);
        children_.push_back(node);
    }
    return node;
}

KeyWordTreeNode * KeyWordTreeNode::GetNext(KeyWordTreeNode *node)
{
    for(size_t i = 0 ; i < children_.size() ; i++)
    {
        if(children_.at(i) == node)
        {
            i++;
            if(i >= children_.size())
            {
                return nullptr;
            }
            else
            {
                return children_.at(i);
            }
        }
    }
    return nullptr;
}

KeyWordTreeNode * KeyWordTreeNode::GetNext()
{
    if(nullptr != parent_)
    {
        KeyWordTreeNode * next = parent_->GetNext(this);
        if(nullptr == next)
        {
            std::cout << "return parent_"<< std::endl;
            return parent_;
        }
        else
        {
            return next;
        }
    }
    return children_.at(0);
}

void KeyWordTreeNode::AddChildrenWithSentence(const std::string &sentence)
{
    std::vector<std::string> keys = SplitWord(sentence);
    AddChildren(keys,0);
}

void KeyWordTreeNode::AddChildren(const std::vector<std::string> &keys,size_t index)
{
    if(index > keys.size()) return;
    if(index < keys.size())
    {
        const std::string &key = keys[index];
        KeyWordTreeNode *child = GetChildWithKey(key);
        if(nullptr == child)
        {
            child = AddChild(key);
        }
        child->AddChildren(keys,++index);
    }
    else
    {
        KeyWordTreeNode *child = GetChildWithKey(KeyWordTreeNode::endKey);
        if(nullptr == child)
        {
            child = AddChild(KeyWordTreeNode::endKey);
        }
    }
}

KeyWordTreeNode *KeyWordTreeNode::GetChildWithKey(const std::string &key)
{
    for (auto it : children_)
    {
        if(it->CompareKey(key) == 0) return it;
    }
    return NULL;
}
